import java.util.*;
import java.text.*;

public class BillManager {

    // 使用Map来存储收入和支出记录，分别存储两种类型的账单
    private static List<Transaction> incomeList = new ArrayList<>();
    private static List<Transaction> expenseList = new ArrayList<>();
    private static double monthlyBudget = 0.0;
    private static Scanner scanner = new Scanner(System.in);
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    // 交易类，表示一条收入或支出记录
    static class Transaction {
        Date date;
        double amount;
        String category;
        String note;

        Transaction(Date date, double amount, String category, String note) {
            this.date = date;
            this.amount = amount;
            this.category = category;
            this.note = note;
        }
    }

    // 记录收入
    public static void recordIncome() {
        System.out.print("请输入收入日期 (yyyy-MM-dd): ");
        String dateStr = scanner.nextLine();
        Date date = parseDate(dateStr);
        if (date == null) return;

        System.out.print("请输入收入金额 (正数): ");
        double amount = parseAmount();
        if (amount <= 0) return;

        System.out.print("请输入收入类别 (如工资、奖金): ");
        String category = scanner.nextLine();

        System.out.print("请输入备注: ");
        String note = scanner.nextLine();

        incomeList.add(new Transaction(date, amount, category, note));
        System.out.println("收入记录成功！");
    }

    // 记录支出
    public static void recordExpense() {
        System.out.print("请输入支出日期 (yyyy-MM-dd): ");
        String dateStr = scanner.nextLine();
        Date date = parseDate(dateStr);
        if (date == null) return;

        System.out.print("请输入支出金额 (正数): ");
        double amount = parseAmount();
        if (amount <= 0) return;

        System.out.print("请输入支出类别 (如餐饮、交通、购物): ");
        String category = scanner.nextLine();

        System.out.print("请输入备注: ");
        String note = scanner.nextLine();

        expenseList.add(new Transaction(date, amount, category, note));
        System.out.println("支出记录成功！");
    }

    // 显示所有账单记录
    public static void displayBills() {
        System.out.println("------ 收入记录 ------");
        for (Transaction t : incomeList) {
            System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
        }

        System.out.println("------ 支出记录 ------");
        for (Transaction t : expenseList) {
            System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
        }
    }

    // 按日期或类别查询账单
    public static void queryBills() {
        System.out.println("选择查询方式：");
        System.out.println("1. 按日期查询");
        System.out.println("2. 按类别查询");
        System.out.println("3. 按日期范围查询");

        int choice = scanner.nextInt();
        scanner.nextLine(); // 清理缓冲区

        switch (choice) {
            case 1:
                System.out.print("请输入日期 (yyyy-MM-dd): ");
                String dateStr = scanner.nextLine();
                Date date = parseDate(dateStr);
                if (date != null) {
                    displayBillByDate(date);
                }
                break;
            case 2:
                System.out.print("请输入类别: ");
                String category = scanner.nextLine();
                displayBillByCategory(category);
                break;
            case 3:
                System.out.print("请输入开始日期 (yyyy-MM-dd): ");
                String startStr = scanner.nextLine();
                Date startDate = parseDate(startStr);
                System.out.print("请输入结束日期 (yyyy-MM-dd): ");
                String endStr = scanner.nextLine();
                Date endDate = parseDate(endStr);
                if (startDate != null && endDate != null) {
                    displayBillByDateRange(startDate, endDate);
                }
                break;
            default:
                System.out.println("无效选择！");
                break;
        }
    }

    // 显示指定日期的账单记录
    public static void displayBillByDate(Date date) {
        System.out.println("------ 收入记录 ------");
        for (Transaction t : incomeList) {
            if (isSameDay(t.date, date)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }

        System.out.println("------ 支出记录 ------");
        for (Transaction t : expenseList) {
            if (isSameDay(t.date, date)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }
    }

    // 显示指定类别的账单记录
    public static void displayBillByCategory(String category) {
        System.out.println("------ 收入记录 ------");
        for (Transaction t : incomeList) {
            if (t.category.equalsIgnoreCase(category)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }

        System.out.println("------ 支出记录 ------");
        for (Transaction t : expenseList) {
            if (t.category.equalsIgnoreCase(category)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }
    }

    // 显示指定日期范围内的账单记录
    public static void displayBillByDateRange(Date startDate, Date endDate) {
        System.out.println("------ 收入记录 ------");
        for (Transaction t : incomeList) {
            if (!t.date.before(startDate) && !t.date.after(endDate)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }

        System.out.println("------ 支出记录 ------");
        for (Transaction t : expenseList) {
            if (!t.date.before(startDate) && !t.date.after(endDate)) {
                System.out.println(sdf.format(t.date) + " | " + t.amount + " | " + t.category + " | " + t.note);
            }
        }
    }

    // 预算管理
    public static void setBudget() {
        System.out.print("请输入每月预算金额: ");
        monthlyBudget = scanner.nextDouble();
        System.out.println("预算设置成功！");
    }

    // 显示当前预算状态
    public static void showBudgetStatus() {
        double totalExpense = 0;
        for (Transaction t : expenseList) {
            totalExpense += t.amount;
        }
        double remainingBudget = monthlyBudget - totalExpense;
        System.out.println("当前剩余预算: " + remainingBudget);
    }

    // 月度统计
    public static void showMonthlyStatistics() {
        double totalIncome = 0, totalExpense = 0;
        for (Transaction t : incomeList) {
            totalIncome += t.amount;
        }
        for (Transaction t : expenseList) {
            totalExpense += t.amount;
        }

        System.out.println("本月总收入: " + totalIncome);
        System.out.println("本月总支出: " + totalExpense);
    }

    // 解析日期
    public static Date parseDate(String dateStr) {
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            System.out.println("日期格式错误，请重新输入！");
            return null;
        }
    }

    // 解析金额
    public static double parseAmount() {
        try {
            double amount = scanner.nextDouble();
            scanner.nextLine(); // 清理缓冲区
            return amount;
        } catch (InputMismatchException e) {
            System.out.println("金额必须为数字，请重新输入！");
            scanner.nextLine(); // 清理缓冲区
            return -1;
        }
    }

    // 判断两个日期是否为同一天
    public static boolean isSameDay(Date d1, Date d2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(d1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(d2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) &&
                cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
    }

    // 显示菜单
    public static void showMenu() {
        System.out.println("------ 个人账单管理系统 ------");
        System.out.println("1. 记录收入");
        System.out.println("2. 记录支出");
        System.out.println("3. 显示所有账单");
        System.out.println("4. 查询账单");
        System.out.println("5. 设置预算");
        System.out.println("6. 显示预算状态");
        System.out.println("7. 显示月度统计");
        System.out.println("8. 退出");

        System.out.print("请选择操作: ");
    }

    public static void main(String[] args) {
        boolean running = true;

        while (running) {
            showMenu();  // 显示菜单

            int choice = scanner.nextInt();
            scanner.nextLine();  // 清理缓冲区

            switch (choice) {
                case 1:
                    recordIncome();  // 记录收入
                    break;
                case 2:
                    recordExpense();  // 记录支出
                    break;
                case 3:
                    displayBills();  // 显示所有账单记录
                    break;
                case 4:
                    queryBills();  // 查询账单
                    break;
                case 5:
                    setBudget();  // 设置预算
                    break;
                case 6:
                    showBudgetStatus();  // 显示预算状态
                    break;
                case 7:
                    showMonthlyStatistics();  // 显示月度统计
                    break;
                case 8:
                    System.out.println("退出系统...");
                    running = false;  // 退出系统
                    break;
                default:
                    System.out.println("无效选择，请重新选择！");
                    break;
            }
        }

        scanner.close();  // 关闭扫描器
    }
}